﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using IOLib;

namespace SheetLib
{
    public static class BlockBitmapCreator
    {
        public const int BlockHeight = 30;
        public const int BlockWidth = 70;
        private const int MinHorFreeSpace = 10;
        private const int MinVertFreeSpace = 6;
        static Font f = new Font("Times New Roman", 10, FontStyle.Bold);

        public static Bitmap G(int index)
        {
            return DrawRoundedRect(10, "g " + index, true);
        }
        public static Bitmap K(int index)
        {
            return DrawRect(10, "K " + index);
        }
        public static Bitmap W(int index)
        {
            return DrawRect(4, "W(s) " + index);
        }
        public static Bitmap W2(int index)
        {
            return DrawRect(4, "W(s²) " + index);
        }
        public static Bitmap F(int index)
        {
            return DrawRect(4, "F(x) " + index);
        }
        public static Bitmap F2(int index)
        {
            int freeInnerHorSpace = 2;
            Bitmap bmp = new Bitmap(BlockWidth, BlockHeight);
            Graphics g = Graphics.FromImage(bmp);
            string s = "F(x₁,x₂) " + index;
            SizeF textSize = g.MeasureString(s, f);
            textSize.Height = (int)textSize.Height;
            textSize.Width = (int)textSize.Width;
            if (textSize.Width > BlockWidth - freeInnerHorSpace - MinHorFreeSpace ||
                textSize.Height > BlockHeight - MinVertFreeSpace)
            {
            }
            else
            {
                int radius = 10;
                int radius2 = 4;
                using (Pen pen = new Pen(Color.Black))
                {
                    GraphicsPath gp = new GraphicsPath();
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2 + radius,
                        MinVertFreeSpace / 2, BlockWidth / 2 - radius2, MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle(BlockWidth / 2 - radius2, MinVertFreeSpace / 2-radius2,
                        2 * radius2 , 2 * radius2), 180, -180);
                    gp.AddLine(BlockWidth / 2 + radius2, MinVertFreeSpace / 2,    
                        (BlockWidth + textSize.Width + freeInnerHorSpace) / 2 - radius,
                        MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle((int)((BlockWidth + textSize.Width +
                        freeInnerHorSpace) / 2 - 2 * radius), MinVertFreeSpace / 2,
                        2 * radius, 2 * radius), 270, 90);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2 + radius, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2 - radius);
                    gp.AddArc(new Rectangle((int)((BlockWidth + textSize.Width
                        + freeInnerHorSpace) / 2 - 2 * radius), BlockHeight - MinVertFreeSpace / 2 -
                        2 * radius, 2 * radius, 2 * radius), 0, 90);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2 - radius,
                        BlockHeight - MinVertFreeSpace / 2, BlockWidth / 2 + radius2,
                        BlockHeight - MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle(BlockWidth / 2 - radius2, BlockHeight - MinVertFreeSpace / 2
                        - radius2, 2 * radius2, 2 * radius2), 0, -180);
                    gp.AddLine(BlockWidth / 2 - radius2, BlockHeight - MinVertFreeSpace / 2,
                        (BlockWidth -textSize.Width - freeInnerHorSpace) / 2 + radius,
                        BlockHeight - MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle((int)((BlockWidth - textSize.Width - freeInnerHorSpace) / 2),
                        BlockHeight - MinVertFreeSpace / 2 - 2 * radius, 2 * radius, 2 * radius), 90, 90);
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2 - radius, (BlockWidth - textSize.Width -
                        freeInnerHorSpace) / 2, MinVertFreeSpace / 2 + radius);
                    gp.AddArc(new Rectangle((int)(BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2, 2 * radius, 2 * radius), 180, 90);
                    gp.CloseFigure();
                    g.FillPath(new SolidBrush(Color.White), gp);
                    g.DrawPath(pen, gp);
                    g.DrawLine(pen, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight / 2, BlockWidth, BlockHeight / 2);
                    g.DrawLine(new Pen(Color.Red), BlockWidth / 2, 0, BlockWidth / 2, 
                        MinVertFreeSpace/2 + radius2);
                    g.DrawLine(new Pen(Color.Blue), BlockWidth / 2, BlockHeight - MinVertFreeSpace/2 - radius2,
                        BlockWidth / 2, BlockHeight);
                    g.DrawString("1", new Font(f.FontFamily, 6,FontStyle.Bold), new SolidBrush(Color.Red),
                        BlockWidth / 2 + radius2, MinVertFreeSpace / 2);
                    g.DrawString("2", new Font(f.FontFamily, 6, FontStyle.Bold), new SolidBrush(Color.Blue),
                        BlockWidth / 2 + radius2, BlockHeight - MinVertFreeSpace / 2 - 10);
                    g.DrawString(s, f, new SolidBrush(Color.Black), (BlockWidth - textSize.Width) / 2,
                        (BlockHeight - textSize.Height) / 2);
                }
            }
            return bmp;
        }
        public static Bitmap Summator(bool[] inverse)
        {
            Bitmap bmp = new Bitmap(BlockWidth, BlockHeight);
            Graphics g = Graphics.FromImage(bmp);
            int radius = Math.Min((BlockHeight - MinVertFreeSpace) / 2, (BlockWidth - MinHorFreeSpace) / 2) - 2;
            using(Pen pen = new Pen(Color.Black))
            {
                int x =BlockWidth / 2 - radius;
                int y =BlockHeight / 2 - radius;
                g.FillEllipse(new SolidBrush(Color.Yellow), x, y,
                    2 * radius, 2 * radius);
                g.DrawEllipse(pen, BlockWidth / 2 - radius, BlockHeight / 2 - radius,
                    2 * radius, 2 * radius);
                g.DrawLine(pen, BlockWidth / 2 + radius, BlockHeight / 2, BlockWidth, BlockHeight / 2);
                g.DrawLine(pen, BlockWidth / 2 - radius, BlockHeight / 2, 0, BlockHeight / 2);
                g.DrawLine(pen, BlockWidth / 2, y, BlockWidth / 2, 0);
                g.DrawLine(pen, BlockWidth / 2, BlockHeight / 2 + radius, BlockWidth / 2, BlockHeight);
                g.TranslateTransform(BlockWidth / 2, BlockHeight / 2);
                g.RotateTransform(45);
                g.TranslateTransform(-BlockWidth / 2, -BlockHeight / 2);
                if (inverse[0])
                {
                    g.FillPie(new SolidBrush(GlobalParams.clr[5]), x, y, 2 * radius, 2 * radius, 360, 90);
                }
                if (inverse[1])
                {
                    g.FillPie(new SolidBrush(GlobalParams.clr[5]), x, y, 2 * radius, 2 * radius, 90, 90);
                }
                if (inverse[2])
                {
                    g.FillPie(new SolidBrush(GlobalParams.clr[5]), x, y, 2 * radius, 2 * radius, 180, 90);
                }
                g.DrawLine(pen, x, BlockHeight / 2, x + 2 * radius, BlockHeight / 2);
                g.DrawLine(pen, BlockWidth / 2, y, BlockWidth / 2, y + 2 * radius);
            }
            return bmp;
        }
        public static Bitmap Y(int index)
        {
            return DrawRoundedRect(10, "y " + index, false);
        }

        private static Bitmap DrawRect(int freeInnerHorSpace, string s)
        {
            Bitmap bmp = new Bitmap(BlockWidth, BlockHeight);
            Graphics g = Graphics.FromImage(bmp);
            SizeF textSize = g.MeasureString(s, f);
            textSize.Height = (int)textSize.Height;
            textSize.Width = (int)textSize.Width;
            if (textSize.Width > BlockWidth - MinHorFreeSpace ||
                textSize.Height > BlockHeight - MinVertFreeSpace)
            {
            }
            else
            {
                using (Pen pen = new Pen(Color.Black))
                {
                    GraphicsPath gp = new GraphicsPath();
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2,
                        (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2, (BlockWidth -
                        textSize.Width - freeInnerHorSpace) / 2, BlockHeight - MinVertFreeSpace / 2);
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2, (BlockWidth - textSize.Width -
                        freeInnerHorSpace) / 2, MinVertFreeSpace / 2);
                    gp.CloseFigure();
                    g.FillPath(new SolidBrush(Color.White), gp);
                    g.DrawPath(pen, gp);
                    g.DrawLine(pen, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight / 2, BlockWidth, BlockHeight / 2);
                    g.DrawLine(pen, (BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        BlockHeight / 2, 0, BlockHeight / 2);
                    g.DrawString(s, f, new SolidBrush(Color.Black), (BlockWidth - textSize.Width) / 2,
                        (BlockHeight - textSize.Height) / 2);
                }
            }
            return bmp;
        }
        private static Bitmap DrawRoundedRect(int freeInnerHorSpace, string s, bool rightCon)
        {
            Bitmap bmp = new Bitmap(BlockWidth, BlockHeight);
            Graphics g = Graphics.FromImage(bmp);
            SizeF textSize = g.MeasureString(s, f);
            textSize.Height = (int)textSize.Height;
            textSize.Width = (int)textSize.Width;
            if (textSize.Width > BlockWidth - freeInnerHorSpace - MinHorFreeSpace ||
                textSize.Height > BlockHeight - MinVertFreeSpace)
            {
            }
            else
            {
                int radius = 10;
                using (Pen pen = new Pen(Color.Black))
                {
                    GraphicsPath gp = new GraphicsPath();
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2 + radius,
                        MinVertFreeSpace / 2,
                        (BlockWidth + textSize.Width + freeInnerHorSpace) / 2 - radius,
                        MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle((int)((BlockWidth + textSize.Width +
                        freeInnerHorSpace) / 2 - 2 * radius), MinVertFreeSpace / 2,
                        2 * radius, 2 * radius), 270, 90);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2 + radius, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2 - radius);
                    gp.AddArc(new Rectangle((int)((BlockWidth + textSize.Width
                        + freeInnerHorSpace) / 2 - 2 * radius), BlockHeight - MinVertFreeSpace / 2 -
                        2 * radius, 2 * radius, 2 * radius), 0, 90);
                    gp.AddLine((BlockWidth + textSize.Width + freeInnerHorSpace) / 2 - radius,
                        BlockHeight - MinVertFreeSpace / 2, (BlockWidth -
                        textSize.Width - freeInnerHorSpace) / 2 + radius, BlockHeight - MinVertFreeSpace / 2);
                    gp.AddArc(new Rectangle((int)((BlockWidth - textSize.Width - freeInnerHorSpace) / 2),
                        BlockHeight - MinVertFreeSpace / 2 - 2 * radius, 2 * radius, 2 * radius), 90, 90);
                    gp.AddLine((BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        BlockHeight - MinVertFreeSpace / 2 - radius, (BlockWidth - textSize.Width -
                        freeInnerHorSpace) / 2, MinVertFreeSpace / 2 + radius);
                    gp.AddArc(new Rectangle((int)(BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                        MinVertFreeSpace / 2, 2 * radius, 2 * radius), 180, 90);
                    gp.CloseFigure();
                    g.FillPath(new SolidBrush(Color.White), gp);
                    g.DrawPath(pen, gp);
                    if (rightCon)
                    {
                        g.DrawLine(pen, (BlockWidth + textSize.Width + freeInnerHorSpace) / 2,
                            BlockHeight / 2, BlockWidth, BlockHeight / 2);
                    }
                    else
                    {
                        g.DrawLine(pen, (BlockWidth - textSize.Width - freeInnerHorSpace) / 2,
                            BlockHeight / 2, 0, BlockHeight / 2);
                    }
                    g.DrawString(s, f, new SolidBrush(Color.Black), (BlockWidth - textSize.Width) / 2,
                        (BlockHeight - textSize.Height) / 2);
                }
            }
            return bmp;
        }
    }
}

